﻿using System;

public class Mapper010 : MapperDefault
{
    internal int latchHi;
    internal int latchHiVal1;
    internal int latchHiVal2;
    internal int latchLo;
    internal int latchLoVal1;
    internal int latchLoVal2;

    public override void init(NES nes)
    {
        base.init(nes);
        this.reset();
    }

    public override void latchAccess(int address)
    {
        bool flag = address < 0x2000;
        address &= 0xff0;
        if (flag)
        {
            if (address == 0xfd0)
            {
                this.latchLo = 0xfd;
                this.loadVromBank(this.latchLoVal1, 0);
            }
            else if (address == 0xfe0)
            {
                this.latchLo = 0xfe;
                this.loadVromBank(this.latchLoVal2, 0);
            }
        }
        else if (address == 0xfd0)
        {
            this.latchHi = 0xfd;
            this.loadVromBank(this.latchHiVal1, 0x1000);
        }
        else if (address == 0xfe0)
        {
            this.latchHi = 0xfe;
            this.loadVromBank(this.latchHiVal2, 0x1000);
        }
    }

    public override void loadROM(ROM rom)
    {
        if (rom.Valid)
        {
            int num = rom.RomBankCount * 4;
            this.loadRomBank(0, 0x8000);
            this.loadRomBank(num - 1, 0xc000);
            this.loadCHRROM();
            this.loadBatteryRam();
            base.nes.Cpu.requestIrq(2);
        }
    }

    public override void mapperInternalStateLoad(ByteBuffer buf)
    {
        base.mapperInternalStateLoad(buf);
        if (buf.readByte() == 1)
        {
            this.latchLo = buf.readByte();
            this.latchHi = buf.readByte();
            this.latchLoVal1 = buf.readByte();
            this.latchLoVal2 = buf.readByte();
            this.latchHiVal1 = buf.readByte();
            this.latchHiVal2 = buf.readByte();
        }
    }

    public override void mapperInternalStateSave(ByteBuffer buf)
    {
        base.mapperInternalStateSave(buf);
        buf.putByte(1);
        buf.putByte((sbyte) this.latchLo);
        buf.putByte((sbyte) this.latchHi);
        buf.putByte((sbyte) this.latchLoVal1);
        buf.putByte((sbyte) this.latchLoVal2);
        buf.putByte((sbyte) this.latchHiVal1);
        buf.putByte((sbyte) this.latchHiVal2);
    }

    public override void reset()
    {
        this.latchLo = 0xfe;
        this.latchHi = 0xfe;
        this.latchLoVal1 = 0;
        this.latchLoVal2 = 4;
        this.latchHiVal1 = 0;
        this.latchHiVal2 = 0;
    }

    public override void write(int address, short value_Renamed)
    {
        if (address < 0x8000)
        {
            base.write(address, value_Renamed);
        }
        else
        {
            value_Renamed = (short) (value_Renamed & 0xff);
            switch ((address >> 12))
            {
                case 10:
                    this.loadRomBank(value_Renamed, 0x8000);
                    return;

                case 11:
                    this.latchLoVal1 = value_Renamed;
                    if (this.latchLo != 0xfd)
                    {
                        break;
                    }
                    this.loadVromBank(value_Renamed, 0);
                    return;

                case 12:
                    this.latchLoVal2 = value_Renamed;
                    if (this.latchLo != 0xfe)
                    {
                        break;
                    }
                    this.loadVromBank(value_Renamed, 0);
                    return;

                case 13:
                    this.latchHiVal1 = value_Renamed;
                    if (this.latchHi != 0xfd)
                    {
                        break;
                    }
                    this.loadVromBank(value_Renamed, 0x1000);
                    return;

                case 14:
                    this.latchHiVal2 = value_Renamed;
                    if (this.latchHi != 0xfe)
                    {
                        break;
                    }
                    this.loadVromBank(value_Renamed, 0x1000);
                    return;

                case 15:
                    if ((value_Renamed & 1) != 0)
                    {
                        base.nes.Ppu.Mirroring = 1;
                        break;
                    }
                    base.nes.Ppu.Mirroring = 0;
                    return;

                default:
                    return;
            }
        }
    }
}

